package pers.cz.transform;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.LoaderClassPath;
import pers.cz.io.IOUtils;

import java.io.FileOutputStream;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

/**
 * @program: postgirl-collection-client
 * @description: DrqueryTransformer
 * @author: Cheng Zhi
 * @create: 2022-05-18 22:34
 **/
public class DrqueryTransformer implements ITransformer{

    public final String TEST_CLASS_NAME = "pers.cz.contorller.TestController";
    //public final String TEST_CLASS_NAME = "com.cz.business.TestCaseBusiness";

    public final String METHOD_NAME = "postQueryFromESB";

    @Override
    public void doInert(String... params) {

    }

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        String finalClassName = className.replace("/", ".");
        if (finalClassName.equals(TEST_CLASS_NAME)) {
            // 动态修改代码
            try {
                ClassPool classPool = new ClassPool(true);
                classPool.insertClassPath(new LoaderClassPath(loader));
                // 获取目标类
                CtClass ctClass = classPool.get(TEST_CLASS_NAME);
                // 获取要监听的方法
                CtMethod beginMethod = ctClass.getDeclaredMethod(METHOD_NAME);
                //beginMethod.insertAfter("com.cz.agent.Collect.begin($args);");

                String src =
                        "{" +
                                " System.out.println(\"监听到了\");" +
                                "pers.cz.mock.DrqueryMock.begin(req, $_);" +
                                "}";
                //beginMethod.insertAt(297, src);
                beginMethod.insertAfter(src);
                //beginMethod.insertAt(68, src);
                // 加载到jvm
                byte[] bytes = ctClass.toBytecode();
                // 保存到桌面
                FileOutputStream fos1= new FileOutputStream("D:\\Java\\Project\\TestMVC\\src\\main\\resources\\TestApi.class");
                fos1.write(bytes);
                IOUtils.close(fos1);
                return bytes;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }
}
